# -*- coding: utf-8 -*-
"""
线性回归算法的评价
Created on Tue Feb 13 20:11:20 2018

@author: Allen
"""
'''
均方误差 MSE （ Mean Squared Error ）
均方根误差 RMSE （ Root Mean Squared Error ） 可以解决MSE量纲的问题
平均绝对误差 MAE （ Mean Absolute Error ） 
'''

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets

# 使用波士顿房价 数据
boston = datasets.load_boston()
x = boston["data"][:, 5] # 只提取其中一个特征做实验
y = boston["target"]

# 将那些都是50的点去掉，使用 fancy index 方法
x = x[y<50]
y = y[y<50]

# 训练集，测试集拆分
from playML.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split( x, y, test_ratio = 0.2, seed = 666 )

# 载入简单线性回归
from playML.SimpleLinearRegression import SimpleLinearRegression2
reg = SimpleLinearRegression2()
reg.fit( x_train, y_train )
y_predict = reg.predict( x_test )

plt.scatter( x_train, y_train )
plt.plot( x_test, y_predict, color = "red" )
plt.show()

# MSE
mse_test = ( np.sum( ( y_test - y_predict ) ** 2 ) ) / len( y_test ) 
#24.156602134387416
# RMSE
from math import sqrt
rmse_test = sqrt( mse_test ) 
#4.914936635846633
# MAE
mae_test = np.sum( np.absolute( y_test - y_predict ) ) / len( y_test ) 
#3.54309744095

# 使用自己写的轮子
from playML.metrics import mean_squared_error
from playML.metrics import root_mean_squared_error
from playML.metrics import mean_absolute_error

mse_test = mean_squared_error( y_test, y_predict ) 
rmse_test = root_mean_squared_error( y_test, y_predict ) 
mae_test = mean_absolute_error( y_test, y_predict ) 

# 使用sklearn内置的方法
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error

mse_test = mean_squared_error( y_test, y_predict ) 
mae_test = mean_absolute_error( y_test, y_predict ) 


'''
结论：
尽量让rmse的值更加小，意义更大一些，这就意味着样本中错误最大的错误值比较小
训练的本质：就是减少最终预测的结果最大的那个误差他们之间相应的差距，这就是为什么选取带平方而不选取绝对值的另一个优势。
'''

# 最好的衡量线性回归法的指标 R Squared
R_Squared = 1 - ( mean_squared_error( y_test, y_predict ) / np.var( y_test ) )
# 0.61293168039373258

# 使用自己造的轮子
from playML.metrics import r2_score
R_Squared1 = r2_score( y_test, y_predict )
# 0.61293168039373258

# 使用sklearn中的方法
from sklearn.metrics import r2_score
R_Squared2 = r2_score( y_test, y_predict )
# 0.61293168039373258

# 使用简单线性回归类中的score方法
R_Squared3 = reg.score( x_test, y_test )
# 0.61293168039373258